#pragma once
#include "SharedDesktopFrame.h"
#include <memory>

template <typename FrameType>
class DesktopCaptureFrameQueue {
public:
	DesktopCaptureFrameQueue() : current_(0) {}
	~DesktopCaptureFrameQueue() = default;

	// Moves to the next frame in the queue, moving the 'current' frame to become
	// the 'previous' one.
	void MoveToNextFrame() { current_ = (current_ + 1) % kQueueLength; }

	// Replaces the current frame with a new one allocated by the caller. The
	// existing frame (if any) is destroyed. Takes ownership of |frame|.
	void ReplaceCurrentFrame(std::unique_ptr<FrameType> frame) {
		frames_[current_] = std::move(frame);
	}

	// Marks all frames obsolete and resets the previous frame pointer. No
	// frames are freed though as the caller can still access them.
	void Reset() {
		for (int i = 0; i < kQueueLength; i++) {
			frames_[i].reset();
		}
		current_ = 0;
	}

	FrameType* current_frame() const { return frames_[current_].get(); }

	FrameType* previous_frame() const {
		return frames_[(current_ + kQueueLength - 1) % kQueueLength].get();
	}

private:
	// Index of the current frame.
	int current_;

	static const int kQueueLength = 2;
	std::unique_ptr<FrameType> frames_[kQueueLength];
	DesktopCaptureFrameQueue(const DesktopCaptureFrameQueue&) = delete;
	DesktopCaptureFrameQueue& operator=(const DesktopCaptureFrameQueue&) = delete;
};

